#include "StdAfx.h"

#include <MyControls/PropertyEditor.h>
#include <xtd/functional>

namespace My {

// PropertyEditor

void PropertyEditor::Open(EditableObject * pObject)
{
	if (!IsEmpty())
		Close();
	if (pObject == 0)
		return;
	m_Objects.push_back(pObject);
	pObject->EditableEvents().Attach(this);
	OpenProperties(pObject->GetProperties());
}

void PropertyEditor::Open(const EditableList & list)
{
	if (!IsEmpty())
		Close();
	if (list.empty())
		return;
	// Determine map of common properties
	EditableList::const_iterator it = list.begin();
	assert(* it != 0);
	PropertyMap map1 = (* it)->GetProperties();
	for (; it != list.end(); ++it) {		
		EditableObject * pObject = * it;
		assert(pObject != 0);
		const PropertyMap & map2 = pObject->GetProperties();
		PropertyMap::iterator pit1;
		for (pit1 = map1.begin(); pit1 != map1.end(); ) {
			PropertyMap::const_iterator pit2 = map2.find((* pit1).first);
			if (pit2 == map2.end() || (* pit2).second != (* pit1).second)
				map1.erase(pit1++);
			else
				++pit1;
		}
	}
	if (map1.empty())
		return;
	m_Objects = list;
	for (it = m_Objects.begin(); it != m_Objects.end(); ++it)
		(* it)->EditableEvents().Attach(this);
	OpenProperties(map1);
}

void PropertyEditor::Close()
{
	GetRows().Clear();
	
	xtd::for_each(m_Rows, xtd::deleter());
	m_Rows.clear();

	for (EditableList::const_iterator it = m_Objects.begin(); it != m_Objects.end(); ++it)
		(* it)->EditableEvents().Detach(this);

	m_Objects.clear();
}

void PropertyEditor::OpenProperties(const PropertyMap & map)
{
	assert(GetRows().IsEmpty());
	assert(m_Rows.empty());

	PropertyMap::const_iterator it;
	for (it = map.begin(); it != map.end(); ++it) {
		PropertyRow * pRow = new PropertyRow(GetRows(), (* it).first, (* it).second);
		m_Rows.push_back(pRow);
		GetRows().Append(pRow);
	}
}

} // My